package com.hentie.spritelib;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.hentie.spritelib.SpriteData.SpriteAnimationInfo;
import com.hentie.spritelib.SpriteData.SpriteFrameInfo;

import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

public final class SpriteXMLParser {
	
	
	public static SpriteData ParseXML(Context context, String filename)
	{
		SpriteData spriteData = new SpriteData();
		
		AssetManager assets = context.getAssets();
		
		Document dom = null;
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder db = null;
		try {
			db = factory.newDocumentBuilder();
		} catch (ParserConfigurationException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
		InputStream is=null;
		try {
			is = assets.open(filename);
		} catch (IOException e2) {
			// TODO Auto-generated catch block
			e2.printStackTrace();
		}
		
		try {
			dom = db.parse(is);
		} catch (SAXException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
		
		int stringIndex = filename.lastIndexOf("/");
		if(stringIndex== -1)
			stringIndex = filename.length()-1;
		
		String directory = filename.substring(0,stringIndex);
		
		//Okay now
		Element root = dom.getDocumentElement();
		//Get the current sprite information
		spriteData.TextureName = directory+"/"+root.getAttribute("imagefile");
		spriteData.totalAnimations = Integer.parseInt(root.getAttribute("totalanims"));
		spriteData.totalFrames = Integer.parseInt(root.getAttribute("totalframes"));
		//Allocate enough frame data
		//Create a temporary Bitmap and get the texture widths and height
		for(int i = 0; i < spriteData.totalFrames; i++)
		{
			spriteData.SpriteFrame.add(null);
		}

		BitmapFactory.Options opts = new BitmapFactory.Options();
		opts.inScaled = false;
		Bitmap tempBitmap = null;
		try {
			tempBitmap = BitmapFactory.decodeStream(context.getAssets().open(spriteData.TextureName),null,opts);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		float textureWidth = tempBitmap.getWidth();
		float textureHeight = tempBitmap.getHeight();
		//Get rid of it
		tempBitmap.recycle();
		
		//Now lets delve deep into the animations
		NodeList animNodes = root.getChildNodes();
		
		for(int i = 0; i < animNodes.getLength(); i++)
		{
			Node currentNode = animNodes.item(i);
			if(currentNode.getNodeType() == Node.ELEMENT_NODE)
			{
				//TypeCast it
				Element animElement = (Element) currentNode;
				
				String animName = animElement.getAttribute("Name");
				//Get anim data
				int firstFrame = Integer.parseInt(animElement.getAttribute("first"));
				int lastFrame = Integer.parseInt(animElement.getAttribute("last"));
				//Add it to the sprite data
				spriteData.SpriteAnimation.put(animName, spriteData.new SpriteAnimationInfo(firstFrame,lastFrame));
				//Now we go through the shide frame nodes and add the frame data
				NodeList frameNodes = animElement.getChildNodes();
				for(int j = 0; j < frameNodes.getLength(); j++)
				{
					Node currentFrameNode = frameNodes.item(j);
					if(currentFrameNode.getNodeType() == Node.ELEMENT_NODE)
					{
						Element frameElement = (Element) currentFrameNode;
						//Frame data
						int frame = Integer.parseInt(frameElement.getAttribute("frame"));
						
						//Texture X,Y cords
						float textureX  = Float.parseFloat(frameElement.getAttribute("tex_x"))/textureWidth;
						float textureY  = Float.parseFloat(frameElement.getAttribute("tex_y"))/textureHeight;
						
						int planeWidth = Integer.parseInt(frameElement.getAttribute("width"));
						int planeHeight = Integer.parseInt(frameElement.getAttribute("height"));
						float texWidth = planeWidth/textureWidth;
						float texHeight = planeHeight/textureHeight;
						
						int frameDelay = Integer.parseInt(frameElement.getAttribute("frameDelay"));
						
						int offsetX= Integer.parseInt(frameElement.getAttribute("offsetX"));
						int offsetY= Integer.parseInt(frameElement.getAttribute("offsetY"));
						
						//Add to the sprite data
						spriteData.SpriteFrame.set(frame, spriteData.new SpriteFrameInfo(textureX, textureY, texWidth, texHeight, planeWidth, planeHeight, frameDelay, offsetX, offsetY));
						
						
						
					}
				}
			}
		}
		
		
		return spriteData;
		
	}
	

}
